// @Author miaoqing
// @Date 2024/02/23 14:57:00
// @Desc
package logic

import (
	"core/command"
	"core/component/function"
	"core/component/logger"
	"errors"
	"sync"
)

var (
	orrOnce         sync.Once
	onlineServerMgr *OnlineServerMgr
)

type OnlineServerMgr struct {
	endpoints *sync.Map
}

func onlineServerMgrGetMe() *OnlineServerMgr {
	orrOnce.Do(func() {
		onlineServerMgr = &OnlineServerMgr{
			endpoints: &sync.Map{},
		}
	})
	return onlineServerMgr
}

func (mgr *OnlineServerMgr) addOnlineServerClient(sc *OnlineClient, srvID, srvAddr string, handleMsgs []uint32, proIndx uint32) {
	val, ok := mgr.endpoints.Load(srvID)
	if ok {
		oldClient, _ := val.(*OnlineClient)
		if sc != oldClient {
			oldClient.Close()
		}
	}
	sc.srvID = srvID
	sc.srvAddr = srvAddr
	sc.proIndx = proIndx
	for _, id := range handleMsgs {
		sc.handleMsgs = append(sc.handleMsgs, uint16(id))
	}
	mgr.endpoints.Store(srvID, sc)
	logger.Infof("Online服务器连接到Gateway服务器  OnlineServer:%v Gateway:%v", srvID, ServerInstance().innerSvcID)
}

func (mgr *OnlineServerMgr) removeServerClient(srvID string) {
	s, ok := mgr.endpoints.Load(srvID)
	if !ok {
		return
	}
	mgr.endpoints.Delete(srvID)
	srv := s.(*OnlineClient)
	clientManagerGetMe().onlineServerDisconnected(srvID, srv.srvAddr, srv.proIndx)
}

func (mgr *OnlineServerMgr) sendMsgToOnlineServer(srvID string, cmd command.Command, msg interface{}) bool {
	client, ok := mgr.endpoints.Load(srvID)
	if !ok {
		return false
	}
	return client.(*OnlineClient).sendMsg(cmd, msg)
}

func (mgr *OnlineServerMgr) getBestOnlineEndpoint() *OnlineClient {
	value := function.RandSyncMap(mgr.endpoints)
	if value == nil {
		return nil
	}
	val, ok := mgr.endpoints.Load(value.(string))
	if !ok {
		return nil
	}
	return val.(*OnlineClient)
}

func (mgr *OnlineServerMgr) getEndpoint(srvID string) (*OnlineClient, error) {
	client, ok := mgr.endpoints.Load(srvID)
	if !ok {
		logger.Warningf("try get scene server error unvalaible service endpoint, srvID:%v ", srvID)
		return nil, errors.New("no endpoints available")
	}
	return client.(*OnlineClient), nil
}

// 由gateway转发到online的消息 全部经过这里发送
func (mgr *OnlineServerMgr) onlineMsgHandler(srvID string, userID uint64, msgID uint16, data []byte) {
	serverClient, ok := mgr.endpoints.Load(srvID)
	if !ok {
		logger.Warningf("unknow server may be server is offline, srvID:%v", srvID)
		return
	}
	msgSend := &command.GatewayForwardPacket{Userid: userID}
	msgSend.Data = make([]byte, len(data))
	copy(msgSend.Data, data)
	serverClient.(*OnlineClient).sendMsg(command.Command_GatewayForwardPacket_Server, msgSend)
}
